﻿using System;
using System.Collections.Generic;
using CID.Domain;
using CID.Web.Models;
using CID.Web.Models.Development;
using CID.Web.Models.Infrastructure;
using CID.Web.Models.Operations;
using CID.Web.Models.Users;
using Rhino.Mocks;

namespace CID.Web.Tests.Controllers
{
    static class ViewModelStubBuilder
    {
        private static string GetRandomString()
        {
            return Guid.NewGuid().ToString();
        }

        private static readonly Dictionary<Type, Func<object>> builderMethodsMap = new Dictionary<Type, Func<object>>();
        static ViewModelStubBuilder() 
        {
            builderMethodsMap.Add(typeof(PackageTypeViewModel), BuildPackageTypeViewModel);
            builderMethodsMap.Add(typeof(TemplateTypeViewModel), BuildTemplateTypeViewModel);
            builderMethodsMap.Add(typeof(UserViewModel), BuildUserViewModel);
            builderMethodsMap.Add(typeof(DeploymentAgentViewModel), BuildDeploymentAgentViewModel);
            builderMethodsMap.Add(typeof(LocationViewModel), BuildLocationViewModel);
            builderMethodsMap.Add(typeof(ComponentViewModel), BuildComponentViewModel);
            builderMethodsMap.Add(typeof(ServerRoleViewModel), BuildServerRoleViewModel);
            builderMethodsMap.Add(typeof(VersionViewModel), BuildVersionViewModel);
            builderMethodsMap.Add(typeof(ReleaseViewModel), BuildReleaseViewModel);
            builderMethodsMap.Add(typeof(TemplateViewModel), BuildTemplateViewModel);
            builderMethodsMap.Add(typeof(EnvironmentViewModel), BuildEnvironmentViewModel);
            builderMethodsMap.Add(typeof(ServerViewModel), BuildServerViewModel);
        }

        public static TViewModel BuildViewModelStub<TViewModel, TModel>(TModel model)
            where TModel : class, IEntity
            where TViewModel : BaseViewModel<TModel>, new()
        {
            return MockRepository.GenerateStub<TViewModel>(model);
        }

        public static TViewModel BuildViewModel<TViewModel, TModel>()
            where TModel : class, IEntity
            where TViewModel : BaseViewModel<TModel>, new()
        {
            return (TViewModel)builderMethodsMap[typeof(TViewModel)]();
        }

        #region Specific ViewModel builder methods
        private static PackageTypeViewModel BuildPackageTypeViewModel()
        {
            var result = MockRepository.GenerateStub<PackageTypeViewModel>();
            result.Name = GetRandomString();
            result.Description = GetRandomString();
            result.Enabled = true;
            return result;
        }
       
        private static TemplateTypeViewModel BuildTemplateTypeViewModel()
        {
            var result = MockRepository.GenerateStub<TemplateTypeViewModel>();
            result.Name = GetRandomString();
            result.Description = GetRandomString();
            result.TemplateContentEditorConverterType = GetRandomString();
            result.TemplateContentEditorViewName = GetRandomString();
            result.Enabled = true;
            return result;
        }

        private static UserViewModel BuildUserViewModel()
        {
            var result = MockRepository.GenerateStub<UserViewModel>();
            result.Name = GetRandomString();
            result.UserName = GetRandomString();
            result.Email = GetRandomString();
            result.Enabled = true;
            return result;
        }

        private static DeploymentAgentViewModel BuildDeploymentAgentViewModel()
        {
            var result = MockRepository.GenerateStub<DeploymentAgentViewModel>();
            result.Name = GetRandomString();
            result.Address = GetRandomString();
            return result;
        }

        private static LocationViewModel BuildLocationViewModel()
        {
            var result = MockRepository.GenerateStub<LocationViewModel>();
            result.Name = GetRandomString();
            result.Description = GetRandomString();
            result.DeploymentAgentId = 1;
            return result;
        }

        private static ComponentViewModel BuildComponentViewModel()
        {
            var result = MockRepository.GenerateStub<ComponentViewModel>();
            result.Name = GetRandomString();
            result.Description = GetRandomString();
            result.RequiredServerRole = GetRandomString();
            result.RequiredServerRoleId = 1;
            result.ResponsibleId = 1;
            return result;
        }

        private static ServerRoleViewModel BuildServerRoleViewModel()
        {
            var result = MockRepository.GenerateStub<ServerRoleViewModel>();
            result.Name = GetRandomString();
            result.Description = GetRandomString();
            return result;
        }

        private static VersionViewModel BuildVersionViewModel()
        {
            var result = MockRepository.GenerateStub<VersionViewModel>();
            result.Name = GetRandomString();
            result.Description = GetRandomString();
            result.ComponentId = 1;
            result.DeploymentTemplateId = null;
            return result;
        }

        private static ReleaseViewModel BuildReleaseViewModel()
        {
            var result = MockRepository.GenerateStub<ReleaseViewModel>();
            result.Name = GetRandomString();
            result.Description = GetRandomString();
            result.ResponsibleId = 1;
            return result;
        }

        private static TemplateViewModel BuildTemplateViewModel()
        {
            var result = MockRepository.GenerateStub<TemplateViewModel>();
            result.Name = GetRandomString();
            result.Description = GetRandomString();
            result.TemplateTypeId = 1;
            return result;
        }

        private static EnvironmentViewModel BuildEnvironmentViewModel()
        {
            var result = MockRepository.GenerateStub<EnvironmentViewModel>();
            result.Name = GetRandomString();
            result.Description = GetRandomString();
            result.ResponsibleId = 1;
            return result;
        }

        private static ServerViewModel BuildServerViewModel()
        {
            var result = MockRepository.GenerateStub<ServerViewModel>();
            result.Name = GetRandomString();
            result.Address = GetRandomString();
            result.LocationId = 1;
            return result;
        }
        #endregion
    }
}
